#include <stdio.h>
#include <stdlib.h>

#include "liso_buffer.h"
#include "liso_logging.h"


liso_buf_t *make_new_buf()
{
	/* malloc liso_buf_t structure */
	liso_buf_t *buf = calloc(1, sizeof(liso_buf_t));
	if (buf == NULL) {
		liso_logging_log("liso_buffer", "make_new_buf",
						"Liso server runs out of memory.\n");
		return NULL;
	}

	/* malloc buffer space */
	buf->liso_buf = calloc(BUF_SIZE, sizeof(char));
	if (buf->liso_buf == NULL) {
		free(buf);
		liso_logging_log("liso_buffer", "make_new_buf",
						"Liso server runs out of memory.\n");
		return NULL;
	}	
	/* initialize structure member */
	buf->buflen = 0;
	buf->bufsize = BUF_SIZE;
	buf->bufptr = buf->liso_buf;
	return buf;
}

int extend_liso_buf(liso_buf_t *buf)
{
	int poffset;
	poffset = buf->bufptr - buf->liso_buf;
	
	char *newbuf = realloc(buf->liso_buf, 
							buf->bufsize + BUF_SIZE);
	if (newbuf == NULL) {
		liso_logging_log("liso_buffer", "extend_liso_buf",
						"Failed to extend liso buffer.\n");
		return -1;
	}

	buf->bufsize += BUF_SIZE;
	buf->bufptr = newbuf + poffset;
	buf->liso_buf = newbuf;
	return 0;
}

void free_liso_buf(liso_buf_t *buf)
{
	if (buf) {
		free(buf->liso_buf);
		free(buf);
	}
}

char *liso_buf_readline(liso_buf_t *lisobuf)
{
	char *strptr;
   	strptr = lisobuf->bufptr;

	while (lisobuf->cnt <= lisobuf->buflen) {
		if (*lisobuf->bufptr != '\n') {
			lisobuf->bufptr++;
			lisobuf->cnt++;
		}	
		else {
			*lisobuf->bufptr = '\0';
			lisobuf->bufptr++;
			lisobuf->cnt++;
			return strptr;
		}
	}

	return NULL;
}
	
int init_cliconn(client_conn_t *cliconn)
{
	/* initialize connection info */
	memset(&cliconn->clientaddr, '\0', sizeof(cliconn->clientaddr));
	cliconn->port = 0;
	cliconn->is_ssl = 0;
	cliconn->is_cgi = 0;

	/* initialize receive buffer*/
	liso_buf_t *recvbuf = make_new_buf();
	if (recvbuf == NULL) {
		liso_logging_log("liso_buffer", "init_cliconn",
						"Liso server runs out of memory.\n");
		return -1;
	}

	cliconn->recvbuf = recvbuf;
	cliconn->sendbuf = NULL;
	return 0;
}

void clear_cliconn(client_conn_t *cliconn)
{		
	free_liso_buf(cliconn->recvbuf);
	free_liso_buf(cliconn->sendbuf);	

	cliconn->recvbuf = NULL;
	cliconn->sendbuf = NULL;
}

void reset_cliconn(client_conn_t *cliconn)
{
	clear_cliconn(cliconn);
	init_cliconn(cliconn);
}

